package com.smallkingson.ylib.db;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import android.annotation.SuppressLint;
import android.database.Cursor;
import android.util.Pair;

import com.smallkingson.ylib.core.Yr;
import com.smallkingson.ylib.core.utils.YBeanUtils;
import com.smallkingson.ylib.db.bean.KeyObtainable;

public class YSqliteUtils {

    /**
     * 用给定的参数填满sql中的问号
     *
     * @param sql
     * @param params
     * @return
     * @throws Exception
     */
    public static String setParamsToSql(String sql, String... params) {
        // 健壮性 判断参数与问好是否相等
        if (params != null) {
            int count = 0;
            for (char c : sql.toCharArray()) {
                if (c == '?') {
                    count++;
                }
            }

            if (count != params.length) {
                try {
                    throw new Exception("参数数量与sql的问好数量不匹配~");
                } catch (Exception e) {
                    Yr.logError(e);
                }
            }
        }
        // 开始

        for (int i = 0; i < params.length; i++) {
            String param = params[i];
            sql = sql.replaceFirst("\\?", param);
        }
        return sql;
    }

    @SuppressLint("NewApi")
    /**
     * 将一条带有有效指针的Currsor里面的数据封装到Bean里
     * @param cursor 有效指针的cursor对象
     * @param BeanClass 目标Bean的Class
     * @return Bean
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws IllegalArgumentException
     * @throws InvocationTargetException
     */
    public static <T> T parseCursorToBean(final Cursor cursor,
                                          Class<T> beanClass) throws Exception {
        final T t = beanClass.newInstance();
        Method[] methods = beanClass.getMethods();

        for (final Method method : methods) {
            if (!method.getName().startsWith("set")) {
                continue;
            }
            final String fieldName = YBeanUtils.getFieldNameFromMethod(method);

            final int index = cursor.getColumnIndex(fieldName);
            Class<?>[] parameterTypes = method.getParameterTypes();
            YBeanUtils.setOnTypeListener(method, parameterTypes[0], new YBeanUtils.OnTypeListener1<Method>() {
                @Override
                public void onInt(Method method) {
                    try {
                        int v = cursor.getInt(index);
                        method.invoke(t, v);
                    } catch (Exception e) {
                        Yr.logError(method.getName(), e);
                    }
                }

                @Override
                public void onFloat(Method method) {
                    try {
                        float v = cursor.getFloat(index);
                        method.invoke(t, v);
                    } catch (Exception e) {
                        Yr.logError(method.getName(), e);
                    }
                }

                @Override
                public void onString(Method method) {
                    try {
                        String v = cursor.getString(index);
                        method.invoke(t, v);
                    } catch (Exception e) {
                        Yr.logError(method.getName(), e);
                    }
                }

                @Override
                public void onBoolean(Method method) {
                    int v = cursor.getInt(index);
                    try {
                        method.invoke(t, v == 1 ? true : false);
                    } catch (Exception e) {
                        Yr.logError(method.getName(), e);
                    }
                }

                @Override
                public void onLong(Method method) {
                    try {
                        long v = cursor.getLong(index);
                        method.invoke(t, v);
                    } catch (Exception e) {
                        Yr.logError(method.getName(), e);
                    }
                }

                @Override
                public void onDouble(Method method) throws Exception {
                    try {
                        float v = cursor.getFloat(index);
                        method.invoke(t, v);
                    } catch (Exception e) {
                        Yr.logError(method.getName(), e);
                    }
                }
            });
//            YBeanUtils.setTypeWatcher(beanClass, fieldName, new YBeanUtils.TypeWatcher() {
//
//                @Override
//                public void onString() {
//
//                    String v = cursor.getString(index);
//
//                    Yr.d();
//                    try {
//                        method.invoke(t, v);
//                    } catch (Exception e) {
//                        Yr.logError(method.getName(), e);
//                    }
//                }
//
//                @Override
//                public void onLongObj() {
//                    Long v = cursor.getLong(index);
//                    Yr.d();
//
//                    try {
//                        method.invoke(t, v);
//                    } catch (Exception e) {
//                        Yr.logError(method.getName(), e);
//                    }
//                }
//
//                @Override
//                public void onLong() {
//                    Yr.d();
//
//                    long v = cursor.getLong(index);
//                    try {
//                        method.invoke(t, v);
//                    } catch (Exception e) {
//                        Yr.logError(method.getName(), e);
//                    }
//                }
//
//                @Override
//                public void onIntObj() {
//                    Yr.d();
//
//                    int v = cursor.getInt(index);
//
//                    try {
//                        method.invoke(t, v);
//                    } catch (Exception e) {
//                        Yr.logError(method.getName(), e);
//                    }
//                }
//
//                @Override
//                public void onInt() {
//                    Yr.d();
//
//                    Integer v = cursor.getInt(index);
//
//                    try {
//                        method.invoke(t, v);
//                    } catch (Exception e) {
//                        Yr.logError(method.getName(), e);
//                    }
//                }
//
//                @Override
//                public void onFloatObj() {
//                    Yr.d();
//
//                    Float v = cursor.getFloat(index);
//
//                    try {
//                        method.invoke(t, v);
//                    } catch (Exception e) {
//                        Yr.logError(method.getName(), e);
//                    }
//                }
//
//                @Override
//                public void onFloat() {
//                    float v = cursor.getFloat(index);
//                    Yr.d();
//
//                    try {
//                        method.invoke(t, v);
//                    } catch (Exception e) {
//                        Yr.logError(method.getName(), e);
//                    }
//                }
//
//                @Override
//                public void onBooleanObj() {
//                    Yr.d();
//
//                    int v = cursor.getInt(index);
//                    try {
//                        method.invoke(t, v == 1 ? true : false);
//                    } catch (Exception e) {
//                        Yr.logError(method.getName(), e);
//                    }
//                }
//
//                @Override
//                public void onBoolean() {
//                    Yr.d();
//
//                    int v = cursor.getInt(index);
//                    try {
//                        method.invoke(t, v == 1 ? true : false);
//                    } catch (Exception e) {
//                        Yr.logError(method.getName(), e);
//                    }
//                }
//
//                @Override
//                public void onDoubleObj() {
//                    Yr.d();
//
//                }
//
//                @Override
//                public void onDouble() {
//                    Yr.d();
//
//                }
//            });
        }
        return t;
    }

    public static String getWhere(KeyObtainable bean) {
        Pair<String, Object>[] pairs = bean.obtainKey();
        StringBuilder sql = new StringBuilder();

        for (Pair pair : pairs) {
            sql.append(pair.first + "=");
            if (YBeanUtils.isNumType(pair.second.getClass())) {
                sql.append(pair.second);
            } else {
                sql.append("'" + pair.second + "'");
            }
            sql.append(" and ");
        }
        sql.append("1=1");
        return sql.toString();
    }
}
